        TITL DAI FIRMWARE 1E5F8-1E7D1  V1.0  Rev.1
        ORG   :E5F8
*
*
*
************
* FPT SQRT *
************
*
* MACC = SQRT (MACC).
*
* Method: approximation followed by Newton
* iterations.
*
* Let X= 2^(2K)*F. Then 2^(2K) is exponent and F
* is mantissa.
*
* Then SQRT(X)=2^K*SQRT(F). 2^K is exp/2.
*      SQRT(F)=P(i):
*          1st approx: P(1)=a*F+b.
*                      0.5<=F<1: values a1 and b1.
*                        1<=F<2: values a2 and b2.
*          Iterations: P(i+1)=(P(i)+F/P(i))/2.
*      Final SQRT(F): P(3).
*
* Exit: All registers preserved.
*
XSQRT   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :EBF1     Exp.byte MACC in A (2K)
        JZ    :E63A     Abort if MACC=0
        RLC
        JC    :E9D0     Run argument error if nr
 REM in MACC is negative
        RLC
        RRC
        RAR
        ORA   A
        RAR             A is exp/2 (K)
        PUSH  PSW       Save it
        MVI   A,:00     Set A=0 if lsb exp =0
        LXI   D,:E65F   Addr a1,b1 for 0.5<=F<1
        JNC   :E618
        INR   A         Set A=1 if lsb exp =1
        LXI   D,:E657   Addr a2,b2 for 1<=F<2
L1E117  MOV   M,A       Init exp byte MACC
        PUSH  H         Save addr MACC
        LXI   H,:00E3
        CALL  :E11C     Copy MACC (F) into 00E3-E6
        XCHG
        PUSH  H         Save addr a/b
        CALL  :EA59     Calc a*F
        POP   H
        INX   H
        INX   H
        INX   H
        INX   H         Pnts to b
        CALL  :EA72     Calc P(1)=a*F+b
        CALL  :E63D     Calc P(2)
        CALL  :E63D     Calc P(3); result in MACC
 REM and reg ABCD
        POP   H         Get addr MACC
        POP   B         Get exp/2 (K) in B
        ADD   B         Add it to exp SQRT(F)
        ANI   :7F       Result must be positive
        MOV   M,A       Final exp.byte into MACC
        NOP
L1E118  JMP   :C14D     Popall, ret
 REM
* Calculate P(i+1):
 REM
L1E119  LXI   H,:00E7
        PUSH  H
        CALL  :E9DB     Copy P(i) into 00E7-EA
        LXI   H,:00E3
        CALL  :E9FB     Copy F from 00E3-E6 into
 REM MACC
        POP   H
        PUSH  H
        CALL  :EA20     Calc F/P(i)
        POP   H
        CALL  :EA72     Calc P(i)+F/P(i)
        DCR   A         exp minus 1: divide by 2
        ANI   :7F       Skip sign bit
        RET
 REM
* CONSTANTS FOR 'XSQRT':
 REM
L1E275  DATA  :7F       a1: 0.578125
        DATA  :D2
        DATA  :D0
        DATA  :1C
*
        DATA  :00       b1: 0.421875
        DATA  :99
        DATA  :EE
        DATA  :14
*
L1E277  DATA  :00       a2: 0.411744
        DATA  :94
        DATA  :00
        DATA  :00
*
        DATA  :7F       b2: 0.601289
        DATA  :D8
        DATA  :00
        DATA  :00
*
***********
* FPT EXP *
***********
*
* MACC = E ^ MACC.
*
* Method: Polynomial approximation.
*
* Let E^X = 2^n * 2^d * 2^z:
*     Then X/ln2 = n + d + z.
*        n: integral portion of the real number.
*        d: a discrete fraction (1/8, 3/8, 5/8
*           or 7/8) of the fractional part.
*        z: remainder: -1/8 <= z <= 1/8.
* Approximation for 2^z:
*     2^z = a0 + a1*z + a2*z^2 + .... + a5*z^5.
*
XEXP    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        LDA   :00D5     Get exp.byte
        STA   :00EF     Save it
        CALL  :E9EE     MACC= ABS(MACC)
        LXI   H,:E72B   Addr 1/ln2
        CALL  :EA59     Calc X/ln2
        CALL  :C21E     Result (n+d+z) on stack
        CALL  :E414     Convert MACC to INT (n)
        CALL  :E133     n in ABCD
        CALL  :C234     Get (n+d+z) from stack
        ORA   B
        ORA   C
        JZ    :E694     Jump if n <= 255
 REM
* If X too big:
 REM
        LDA   :00EF     Get exp.byte
        CMA             Take complement
        ORA   A         Set flags for error
        STC             Init error exit
        JMP   :E6F5     Run error, abort
 REM
* Find d:
 REM
L1E121  PUSH  D         Save n
        CALL  :E154     MACC = FRAC (MACC)
        LXI   D,:E6FB   Addr FPT(1/8)
        LHLD  :00D5
        ORA   L
        JZ    :EFF9
        CPI   :7F
        JC    :E6B8
        LXI   D,:E6FF   Addr FPT(3/8)
        JMP   :E6B8
L1E122  RLC
        RLC
        LXI   D,:E703   Addr FPT(5/8)
        JNC   :E6B8
        LXI   D,:E707   Addr FPT(7/8)
*
L1E123  XCHG            Addr d in HL
        PUSH  H         Save it
        CALL  :EA6D     MACC= MACC-d (z)
        MOV   E,A       Exp. z in E
        LDA   :00EF     Get exp. X
        RLC             Sign into carry
        PUSH  PSW       Save sign
        MOV   A,E       Get exp. z
        CC    :E9E4     Evt. change sign
        LXI   H,:00E3
        CALL  :E9DB     Copy z into 00E3-E6
        CALL  :E9DB     and in 00E7-EA
        LXI   H,:C462   Addr a0 (FPT(1))
        CALL  :E9FB     Copy a0 into MACC
        LXI   H,:E72F   Addr table a1-a5
        CALL  :E5AA     Calc Taylor sum 2^z
        POP   PSW       Get exp.byte X SHL 1,
 REM sign in CY
        POP   D         Get addr FPT(n/8)
        PUSH  PSW
        LXI   H,:0010   Init offset for table L1E283
        JNC   :E6E6     Jump if X was positive
        DAD   H         Offset is #0020 for neg.nr.
L1E124  DAD   D         Calc addr in L1E283
        CALL  :EA59     Calc 2^z * 2^d
        POP   PSW       Get CY on sign of X
        POP   H         Get n in H
        MOV   A,H
        JNC   :E6F2     Jump if X was positive
        CMA             ) Else: complement n
        INR   A         )
L1E125  CALL  :C1B7     Add exponents (n+d+z)
L1E126  CC    :EA4B     Evt error handling
L1E127  JMP   :C14D     Popall, ret
 REM
* CONSTANTS FOR 'XEXP':
 REM
L1E279  DATA  :7E       FPT(1/8)
        DATA  :80
        DATA  :00
        DATA  :00
*
L1E280  DATA  :7F       FPT(3/8)
        DATA  :C0
        DATA  :00
        DATA  :00
*
L1E281  DATA  :00       FPT(5/8)
        DATA  :A0
        DATA  :00
        DATA  :00
*
L1E282  DATA  :00       FPT(7/8)
        DATA  :E0
        DATA  :00
        DATA  :00
*
*
L1E283  DATA  :01       2^(1/8)
        DATA  :8B
        DATA  :95
        DATA  :C2
*
        DATA  :01       2^(3/8)
        DATA  :A5
        DATA  :FE
        DATA  :D7
*
        DATA  :01       2^(5/8)
        DATA  :C5
        DATA  :67
        DATA  :2A
*
        DATA  :01       2^(7/8)
        DATA  :EA
        DATA  :C0
        DATA  :C7
*
L1E287  DATA  :00       2^(-1/8)
        DATA  :EA
        DATA  :C0
        DATA  :C7
*
        DATA  :00       2^(-3/8)
        DATA  :C5
        DATA  :67
        DATA  :2A
*
        DATA  :00       2^(-5/8)
        DATA  :A5
        DATA  :FE
        DATA  :D7
*
        DATA  :00       2^(-7/8)
        DATA  :8B
        DATA  :95
        DATA  :C2
*
*
L1E291  DATA  :01       1/LN2
        DATA  :B8
        DATA  :AA
        DATA  :3B
*
*
L1E292  DATA  :00       a1: LN2
        DATA  :B1       0.69314718057
        DATA  :72
        DATA  :18
*
        DATA  :7E       a2: ((LN2)^2)/2!
        DATA  :F5       0.24022648580
        DATA  :FD
        DATA  :EF
*
        DATA  :7C       a3: ((LN2)^3)/3!
        DATA  :E3       0.055504105406
        DATA  :58
        DATA  :46
*
        DATA  :7A       a4: ((LN2)^4)/4!
        DATA  :9D       0.0096217389747
        DATA  :A4
        DATA  :81
*
        DATA  :77       a5: ((LN2)^5)/5!
        DATA  :AE       0.0013337729375
        DATA  :D1
        DATA  :FE
*
        DATA  :00       End of table
        DATA  :00
*
*******
* LOG *
*******
*
* MACC = LN (MACC).
*
* Method: Polynomial approximation.
*
* Write X = 2^K * F (normalized written), with
* 0.5<= F <1.
*   If F < SQR(2)/2: J=K-1, G=2*F.
*   If F > SQR(2)/2: J=K,   G=F.
* Now X = 2^J * G.
*
* Assume G=(1+v)/(1-v), then:
*       ln(X) = J*ln(2) + ln((1+v)/(1-v)).
*
* ln((1+v)/(1-v))=2(v+v^3/3+v^5/5+...+v^9/9).
* Only terms up to v^9 are used. The term constants
* are adjusted for minimum error.
*
* Exit: 00E3-E6: Last significant summand.
*       00E7-EA: v^2.
*       00EB-EE: Entry MACC (X).
*       MACC:    Result.
*       All registers preserved.
*
XLN     PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        CALL  :EBF1     Check contents MACC
        JZ    :E9D0     Run argument error if
 REM MACC = 0
        ORA   A
        JM    :E9D0     Error if nr is negative
        CALL  :C1E9     Sign extend exp (=K)
        PUSH  PSW       Save sign extended exp
        MVI   M,:00     Frig exponent
        LDA   :00D6     Get hibyte mantissa
        CPI   :B5       Compare with SQR(2)/2
        JNC   :E76A     if F < SQR(2)/2
 REM
* If F > SQR(2)/2:
 REM
        LXI   H,:C466   Addr FPT(2)
        CALL  :EA59     Calc MACC = 2*F (=G)
        POP   PSW       Get K
        DCR   A         J=K-1
        PUSH  PSW       Save J
*
FLNA    LXI   H,:C462   Addr FPT(1)
        CALL  :EA72     MACC = G+1
        CALL  :C21E     save G+1 on stack
        LXI   H,:C466   Addr FPT(2)
        CALL  :EA6D     MACC = G-1
        LXI   H,:0000
        DAD   SP        HL=SP
        CALL  :EA20     MACC = (G-1)/(G+1) (=v)
        INX   SP        )
        INX   SP        ) Suppress 4 bytes
        INX   SP        ) on stack
        INX   SP        )
        LXI   H,:00E3
        CALL  :E9DB     Copy v into 00E3-E6
        PUSH  H         Pnts to 00E7
        CALL  :C21E     Save v on stack
        LXI   H,:0000
L1E273  DAD   SP        HL=SP
        CALL  :EA59     MACC = v^2
        INX   SP        )
        INX   SP        ) Suppress 4 bytes
        INX   SP        ) on stack
        INX   SP        )
        POP   H         HL=00E7
        CALL  :E9DB     Copy v^2 into 00E7-EA
        POP   D         Get J in D
        MOV   A,D       )
        RAL             )
        SBB   A         ) Convert J from 1 byte
        MOV   B,A       ) into 4 byte into ABCD
        MOV   C,A       )
        CALL  :E126     Copy ABCD into MACC
        CALL  :E3DE     MACC = INT(MACC)
        LXI   H,:E7B8   Addr ln(2)
        CALL  :EA59     MACC=MACC*ln(2) (=J*ln(2))
        LXI   H,:E7BC   Addr Taylor sum constants
        CALL  :E5AA     Calc Taylor sum (= ln(X))
        JMP   :C14D     Popall, ret
 REM
* CONSTANTS FOR 'XLN':
 REM
L1E298  DATA  :00       LN(2)
        DATA  :B1
        DATA  :72
        DATA  :18
*
L1E299  DATA  :02       b1: FPT (2)
        DATA  :80
        DATA  :00
        DATA  :00
*
        DATA  :00       b3: about 2/3
        DATA  :AA       0.666666564181
        DATA  :AA
        DATA  :A9
*
        DATA  :7F       b5: about 2/5
        DATA  :CC       0.400018840613
        DATA  :CF
        DATA  :45
*
        DATA  :7F       b7: about 2/7
        DATA  :91       0.2845357266
        DATA  :AE
        DATA  :AB
*
        DATA  :7E       b9: about 2/9
        DATA  :80       0.125
        DATA  :00
        DATA  :00
*
        DATA  :00       End of table
        DATA  :00
*
*
*
        END
